home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Dev / misc / temgen.lha / Temgen / tg-0.11 / func.c < prev    next >
C/C++ Source or Header  |  2002-12-18  |  7KB  |  307 lines

  1. #include "alloc.h"
  2. #include "atom.h"
  3. #include "eval.h"
  4. #include "func.h"
  5. #include "generator.h"
  6. #include "hash.h"
  7. #include "output.h"
  8. #include "omani.h"
  9. #include "printf.h"
  10. #include "strbuf.h" 
  11. #include "sysdefs.h"
  12. #include "util.h"
  13.  
  14. struct function {
  15.     int name;
  16.     int file; 
  17.     int line;
  18. };
  19.  
  20. static struct hash *funtab = 0;
  21. static struct hash *systab = 0;
  22.  
  23. #define     FHSIZE    701       /* TODO tune */
  24.  
  25. static unsigned fhval( const void *data )
  26. {
  27.     return ((const struct function*)data)->name;
  28. }
  29.  
  30. static int fhcmp( const void *f1, const void *f2 )
  31. {
  32.     int name1, name2;
  33.     name1 = ((const struct function*)f1)->name;
  34.     name2 = ((const struct function*)f2)->name;
  35.     return name1-name2;
  36. }
  37.  
  38. int regfun( const char *name, int file, int line )
  39. {
  40.     struct function *f;
  41.  
  42.     if ( !funtab ) funtab = new_hash( FHSIZE, fhval, fhcmp );
  43.     if ( !funtab ) return -1;
  44.     
  45.     f = (struct function*)MALLOC( sizeof(*f) );
  46.     f->name = atom(name);
  47.     f->file = file;
  48.     f->line = line;
  49.     return h_add( funtab, f );
  50. }
  51.  
  52. int findfun( int name, int *file, int *line )
  53. {
  54.     struct function f, *res;
  55.     
  56.     f.name = name;
  57.     res = (struct function*)h_get( funtab, &f );
  58.     if ( res ) {
  59.         *file = res->file;
  60.         *line = res->line;
  61.         return 0;
  62.     }
  63.  
  64.     return 1;
  65. }
  66.  
  67. static unsigned sys_hash( const void *ptr )
  68. {
  69.     return ((const struct sysfun*)ptr)->name;
  70. }
  71.  
  72. static int sys_cmp( const void *p1, const void *p2 )
  73. {
  74.     int n1, n2;
  75.     n1 = ((const struct sysfun*)p1)->name;
  76.     n2 = ((const struct sysfun*)p2)->name;
  77.     return n1-n2;
  78. }
  79.  
  80. /* "$output" removed - use "@output" ! */
  81. #if 0
  82. static int sys_output( void )
  83. {
  84.     int arg = refvar( atom( "a" ), 1 );
  85.     if ( arg < 0 ) return -1;             /* TODO okreslic semantyke */
  86.     setout( atom( ob_gets(arg) ), 0 ); 
  87.     return 0;
  88. }
  89. #endif
  90.  
  91. static int sys_printf( void )
  92. {
  93.         char buf[ PRINTF_BUFFER_SIZE ];
  94.         int arg = refvar( atom("a"), 1 );
  95.         int i, p;
  96.         char *fmt;
  97.         int args[ MAX_NARGS ];
  98.         char name[ 2 ] = "a";
  99.         
  100.         fmt = ob_gets( arg );
  101.         for ( i=1; i<MAX_NARGS; i++ ) {
  102.                 name[ 0 ] = 'a' + i;
  103.                 p = refvar( atom(name), 1 );
  104.                 if ( p < 0 ) break;
  105.                 args[ i-1 ] = p;
  106.         }
  107.  
  108.         snprintfo( buf, sizeof(buf), fmt, args, i );
  109.         setrets( buf );
  110.         return 0;
  111. }
  112.  
  113. static int sys_number( void )
  114. {
  115.     const char *s;
  116.     double x;
  117.     int n;
  118.     int typ;
  119.     int arg = refvar( atom("a"), 1 );
  120.     
  121.     typ = ob_type( arg );
  122.     switch( typ ) {
  123.         case 'i':
  124.             setreti( ob_geti(arg) );
  125.             break;
  126.         case 'f':
  127.             setretf( ob_getf(arg) );
  128.             break;
  129.         case 's':
  130.             s = ob_gets(arg);
  131.             x = strtod( s, NULL );
  132.             n = atoi( s );
  133.             if ( n == x )
  134.                 setreti( n );
  135.             else
  136.                 setretf( x );
  137.             break;
  138.         default:
  139.             setreti( 0 );
  140.     }
  141.     
  142.     return 0;
  143. }
  144.  
  145. static int sys_size( void )
  146. {
  147.     int arg = refvar( atom( "a" ), 1 );
  148.     if ( arg < 0 ) return 0;
  149.     setreti( ob_count( arg ) ); 
  150.     return 0;
  151. }
  152.  
  153. static int sys_strlen( void )
  154. {
  155.     char *s;
  156.     int arg = refvar( atom( "a" ), 1 );
  157.     if ( arg < 0 ) return 1;
  158.     s = ob_gets( arg );
  159.     setreti( s ? strlen(s): 0 ); 
  160.     return 0;
  161. }
  162.  
  163. static int sys_substr( void )
  164. {
  165.     char *s, *res;
  166.     int len;
  167.     int a = refvar( atom( "a" ), 1 );
  168.     int b = refvar( atom( "b" ), 1 );
  169.     int c = refvar( atom( "c" ), 1 );
  170.     s = ob_gets( a );
  171.     if ( !s ) {
  172.         setrets( "" );
  173.         return 0;
  174.     }
  175.     len = strlen( s );
  176.     b = ob_geti( b );
  177.     c = (c>=0) ? ob_geti( c ): -1;
  178.     if ( c >= 0 ) {
  179.         if ( b + c > len )
  180.             len = len - b;
  181.         else
  182.             len = c;
  183.     } 
  184.     res = (char*)ALLOCA( len + 1 );
  185.     if ( !res ) return -1;
  186.     memcpy( res, s+b, len );
  187.     res[ len ] = '\0';
  188.     setrets( res );
  189.     return 0;
  190. }
  191.  
  192. static int sys_system( void )
  193. {
  194.     char *s;
  195.     int exitcode;
  196.     
  197.     int a = refvar( atom( "a" ), 1 );
  198.     s = ob_gets( a );
  199.     if ( s && s[0] ) {
  200.         FILE *f;
  201.         struct strbuf *out;
  202.         char buf[ SYSTEM_BUFFER_SIZE ];
  203.         out = new_strbuf( SYSTEM_BUFFER_SIZE, SYSTEM_BUFFER_SIZE );
  204.         if ( !out ) return -1;
  205.         
  206.         f = popen( s, "r" );
  207.         if ( !f ) {
  208.             free_strbuf( out );
  209.             return -1;
  210.         }
  211.         
  212.         while( fgets( buf, sizeof(buf), f )) {
  213.             if ( sb_cat( out, buf, strlen(buf) ) ) {
  214.                 pclose( f );
  215.                 free_strbuf( out );
  216.                 return -1;
  217.             }
  218.         }
  219.  
  220.         exitcode = pclose( f );
  221.         setrets( sb_data( out ) );
  222.         
  223.         if ( WIFEXITED(exitcode) )    
  224.             exitcode = WEXITSTATUS(exitcode);
  225.         else
  226.             exitcode = -1;
  227.         
  228.         ob_set( ob_field( system_obj(), atom("exitcode")), 'i', exitcode );
  229.         free_strbuf( out );
  230.     }
  231.     return 0;
  232. }
  233.  
  234. static int sys_tplfile( void )
  235. {
  236.     extern int cur_file;
  237.     setrets( atom_name(cur_file) );
  238.     return 0;
  239. }
  240.  
  241. static int sys_tplline( void )
  242. {
  243.     extern int cur_cmd;
  244.     setreti( cur_cmd+1 );
  245.     return 0;
  246. }
  247.  
  248. static struct sysfun *new_sysfun( const char *name, int (*f)(void), int npar )
  249. {
  250.     struct sysfun *fun;
  251.     struct param *params = NULL;
  252.     int i;
  253.     
  254.     params = (struct param*)CALLOC( npar, sizeof(params[0]));
  255.     if ( npar>0 && !params ) {
  256.             fatal( "memory allocation error" );
  257.             return NULL;
  258.     }
  259.     
  260.     fun = (struct sysfun*)MALLOC( sizeof(*fun) );
  261.     if ( fun ) {
  262.         
  263.         for ( i=0; i<npar; i++ ) {
  264.                 char name[2] = "a";
  265.                 params[i].h = i ? params+i-1: 0;
  266.                 name[0] = 'a' + i; 
  267.                 params[i].t = atom( name );
  268.         }    
  269.  
  270.         if ( npar > 0 ) 
  271.                 fun->par = params + npar-1;
  272.         else
  273.                 fun->par = NULL;
  274.         
  275.         
  276.         fun->name = atom( name );
  277.         fun->fun = f;
  278.     }
  279.     
  280.     return fun;
  281. }
  282.  
  283. static void initsystab( void )
  284. {
  285.     systab = new_hash( 43, sys_hash, sys_cmp );   /* tuning ? */
  286.     h_add( systab, new_sysfun( "number",  sys_number,  1 ));
  287.     h_add( systab, new_sysfun( "printf",  sys_printf, MAX_NARGS ));
  288.     h_add( systab, new_sysfun( "size",    sys_size,    1 ));
  289.     h_add( systab, new_sysfun( "strlen",  sys_strlen,  1 ));
  290.     h_add( systab, new_sysfun( "substr",  sys_substr,  3 ));
  291.     h_add( systab, new_sysfun( "system",  sys_system,  1 ));
  292.     h_add( systab, new_sysfun( "tplfile", sys_tplfile, 0 ));
  293.     h_add( systab, new_sysfun( "tplline", sys_tplline, 0 ));
  294. }
  295.  
  296. struct sysfun *findsys( int name )
  297. {
  298.     struct sysfun key;
  299.     if ( !systab ) initsystab();
  300.     if ( !systab ) {
  301.             fatal( "memory allocation error" );
  302.             return 0;  
  303.     }
  304.     key.name = name;
  305.     return (struct sysfun*)h_get( systab, &key );
  306. }
  307.